package com.dji.sample.control.controller;

import com.dji.sample.control.model.enums.DroneAuthorityEnum;
import com.dji.sample.control.model.enums.RemoteDebugMethodEnum;
import com.dji.sample.control.model.param.*;
import com.dji.sample.control.service.IControlService;
import com.dji.sdk.cloudapi.debug.RemoteDebugResponse;
import com.dji.sdk.cloudapi.debug.api.AbstractDebugService;
import com.dji.sdk.common.HttpResultResponse;
import com.dji.sdk.common.SDKManager;
import com.dji.sdk.mqtt.services.ServicesReplyData;
import com.dji.sdk.mqtt.services.TopicServicesResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.validation.Valid;

/**
 * 机场（Dock）控制器类。
 * 
 * 该控制器提供了对大疆机场（Dock）及其搭载无人机的远程控制能力，包括：
 * 1. 远程调试功能
 * 2. 指点飞行控制
 * 3. 指定点位起飞
 * 4. 控制权限争夺
 * 5. 负载设备（如云台相机）控制
 * 
 * 通过RESTful API接口，第三方系统可以远程操控设备，实现自动化任务执行。
 * 
 * @author sean
 * @version 1.2
 * @date 2022/7/29
 */
@RestController
@Slf4j
@RequestMapping("${url.control.prefix}${url.control.version}/devices")
public class DockController {

    /**
     * 控制服务接口，提供实际的控制逻辑实现
     */
    @Autowired
    private IControlService controlService;

    @Resource
    private  AbstractDebugService  abstractDebugService;

    /**
     * 创建远程调试任务。
     * 该接口用于对指定机场设备执行远程调试操作，如开关机、重启等。
     * 
     * @param sn 设备序列号，用于唯一标识设备
     * @param serviceIdentifier 服务标识符，指定要执行的调试命令类型
     * @param param 远程调试参数，包含执行调试所需的具体参数
     * @return HttpResultResponse 操作结果响应
     */
    @PostMapping("/{sn}/jobs/{service_identifier}")
    public HttpResultResponse createControlJob(@PathVariable String sn,
                                               @PathVariable("service_identifier") String serviceIdentifier,
                                               @Valid @RequestBody(required = false) RemoteDebugParam param) {
        return controlService.controlDockDebug(sn, RemoteDebugMethodEnum.find(serviceIdentifier), param);
    }

    /**
     * 飞向指定点位。
     * 控制无人机飞行到指定的经纬度坐标点。
     * 
     * @param sn 设备序列号，用于唯一标识设备
     * @param param 飞行点位参数，包含目标经纬度、高度等信息
     * @return HttpResultResponse 操作结果响应
     */
    @PostMapping("/{sn}/jobs/fly-to-point")
    public HttpResultResponse flyToPoint(@PathVariable String sn, @Valid @RequestBody FlyToPointParam param) {
        return controlService.flyToPoint(sn, param);
    }

    /**
     * 停止飞向点位任务。
     * 中断当前正在执行的飞向点位任务。
     * 
     * @param sn 设备序列号，用于唯一标识设备
     * @return HttpResultResponse 操作结果响应
     */
    @DeleteMapping("/{sn}/jobs/fly-to-point")
    public HttpResultResponse flyToPointStop(@PathVariable String sn) {
        return controlService.flyToPointStop(sn);
    }

    /**
     * 从指定点位起飞。
     * 控制无人机从当前位置起飞并飞向指定点位。
     * 
     * @param sn 设备序列号，用于唯一标识设备
     * @param param 起飞点位参数，包含目标经纬度、高度等信息
     * @return HttpResultResponse 操作结果响应
     */
    @PostMapping("/{sn}/jobs/takeoff-to-point")
    public HttpResultResponse takeoffToPoint(@PathVariable String sn, @Valid @RequestBody TakeoffToPointParam param) {
        return controlService.takeoffToPoint(sn, param);
    }

    /**
     * 夺取飞行控制权限。
     * 允许云端获取无人机的飞行控制权，用于执行自动化飞行任务。
     * 
     * @param sn 设备序列号，用于唯一标识设备
     * @return HttpResultResponse 操作结果响应
     */
    @PostMapping("/{sn}/authority/flight")
    public HttpResultResponse seizeFlightAuthority(@PathVariable String sn) {
        return controlService.seizeAuthority(sn, DroneAuthorityEnum.FLIGHT, null);
    }

    /**
     * 夺取负载设备控制权限。
     * 允许云端获取无人机负载设备（如相机、云台等）的控制权。
     * 
     * @param sn 设备序列号，用于唯一标识设备
     * @param param 负载设备参数，指定要控制的负载设备信息
     * @return HttpResultResponse 操作结果响应
     */
    @PostMapping("/{sn}/authority/payload")
    public HttpResultResponse seizePayloadAuthority(@PathVariable String sn, @Valid @RequestBody DronePayloadParam param) {
        return controlService.seizeAuthority(sn, DroneAuthorityEnum.PAYLOAD, param);
    }

    /**
     * 发送负载设备命令。
     * 向无人机的负载设备（如相机、云台等）发送控制命令。
     * 
     * @param sn 设备序列号，用于唯一标识设备
     * @param param 负载命令参数，包含要执行的具体命令和参数
     * @return HttpResultResponse 操作结果响应
     * @throws Exception 当命令执行过程中发生错误时抛出异常
     */
    @PostMapping("/{sn}/payload/commands")
    public HttpResultResponse payloadCommands(@PathVariable String sn, @Valid @RequestBody PayloadCommandsParam param) throws Exception {
        param.setSn(sn);
        return controlService.payloadCommands(param);
    }

    /**
     * 关闭舱盖
     * @param dockSn
     * @return
     */
    @PutMapping("/{sn}/dock/cover-close")
    public HttpResultResponse coverClose(@PathVariable(value = "sn") String dockSn) {
        log.info("closeCover");
       return controlService.coverClose(dockSn);
    }

    @PutMapping("/{sn}/dock/cover-force-close")
    public HttpResultResponse coverForceClose(@PathVariable(value = "sn") String dockSn) {
        log.info("coverForceClose");
        return controlService.coverForceClose(dockSn);
    }
    @PutMapping("/{sn}/dock/cover-open")
    public HttpResultResponse coverOpen(@PathVariable(value = "sn") String dockSn) {
        log.info("coverOpen");
        return controlService.coverOpen(dockSn);
    }


    @PutMapping("/{sn}/dock/debug-mode-open")
    public HttpResultResponse debugModeOpen(@PathVariable(value = "sn") String dockSn) {
        log.info("debugModeOpen");
        return controlService.debugModeOpen(dockSn);
    }
}
